package com.yzh.openai.domain.order.service;

import com.yzh.lantu.common.PayUtils;
import com.yzh.lantu.common.Transaction;
import com.yzh.lantu.model.wx.request.WxNativePayRequest;
import com.yzh.lantu.model.wx.response.WxNativePayResponse;
import com.yzh.lantu.service.wx.NativePayService;
import com.yzh.openai.domain.order.model.aggregates.CreateOrderAggregate;
import com.yzh.openai.domain.order.model.entity.OrderEntity;
import com.yzh.openai.domain.order.model.entity.PayOrderEntity;
import com.yzh.openai.domain.order.model.entity.ProductEntity;
import com.yzh.openai.domain.order.model.valobj.OrderStatusVO;
import com.yzh.openai.domain.order.model.valobj.PayStatusVO;
import com.yzh.openai.domain.order.model.valobj.PayTypeVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class OrderService extends AbstractOrderService {
    @Value("${lantu.wxpay.config.developer-appid}")
    private String appid;
    @Value("${lantu.wxpay.config.mch-id}")
    private String mchid;
    @Value("${lantu.wxpay.config.notify-url}")
    private String notifyUrl;
    @Value("${lantu.wxpay.config.time-expire}")
    private String timeExpire;
    @Value("${lantu.wxpay.config.partner-key}")
    private String partnerKey;

    @Resource
    private NativePayService nativePayService;

    @Override
    protected OrderEntity saveOrder(String openid, ProductEntity productEntity) {
        OrderEntity orderEntity = new OrderEntity();
        //数据库有幂等拦截，订单ID是唯一索引，重复订单会主键冲突。一般公司都会用雪花算法生成
        orderEntity.setOrderId(RandomStringUtils.randomNumeric(12));
        orderEntity.setOrderTime(new Date());
        orderEntity.setOrderStatus(OrderStatusVO.CREATE);
        orderEntity.setTotalAmount(productEntity.getPrice());
        orderEntity.setPayTypeVO(PayTypeVO.WEIXIN_NATIVE);

        //聚合信息
        CreateOrderAggregate createOrderAggregate = new CreateOrderAggregate();
        createOrderAggregate.setOpenid(openid);
        createOrderAggregate.setProduct(productEntity);
        createOrderAggregate.setOrder(orderEntity);

        //保存订单：订单和支付是两个部分，一个是数据库操作，一个是HTTP请求，所以不能用事务处理，只能先保存订单再创建支付单，如果失败则需要任务补偿
        orderRepository.saveOrder(createOrderAggregate);
        return orderEntity;
    }

    @Override
    protected PayOrderEntity doPrepayOrder(String openid, String orderId, String productName, BigDecimal amountTotal) {
        //创建蓝兔微信支付请求
        WxNativePayRequest payRequest = new WxNativePayRequest();
        payRequest.setMch_id(mchid);
        payRequest.setOut_trade_no(orderId);
        payRequest.setTotal_fee(amountTotal.toString());
        payRequest.setBody(productName);
        payRequest.setTimestamp(System.currentTimeMillis() / 1000 + "");
        payRequest.setNotify_url(notifyUrl);
        payRequest.setTime_expire(timeExpire);
        payRequest.setDeveloper_appid(appid);
        payRequest.setSign(PayUtils.createSign(PayUtils.objectToMap(payRequest), partnerKey));


        //回调Url  
        String codeUrl = "";
        WxNativePayResponse payResponse = null;
        try {
            //调用蓝兔SDK微信支付接口
            if (null != nativePayService) {
                payResponse = nativePayService.prepay(payRequest);
            } else {
                codeUrl = "未配置支付渠道，不能生成支付URL";
            }

            if (Transaction.PayCode.SUCCESS.getCode().equals(payResponse.getCode())) {
                codeUrl = payResponse.getData().getCode_url();
            } else {
                throw new Exception(payResponse.getMsg());
            }
        } catch (Exception e) {
            log.error("创建支付-失败：{}", e.getMessage());
        }


        PayOrderEntity payOrderEntity = new PayOrderEntity();
        payOrderEntity.setOpenid(openid);
        payOrderEntity.setOrderId(orderId);
        payOrderEntity.setPayUrl(codeUrl);
        payOrderEntity.setPayStatus(PayStatusVO.WAIT);

        //更新订单支付信息 
        orderRepository.updateOrderPayInfo(payOrderEntity);
        return payOrderEntity;
    }

    @Override
    public boolean changeOrderPaySuccess(String orderId, String transactionId, BigDecimal totalAmount, Date payTime) {
        return orderRepository.changeOrderPaySuccess(orderId, transactionId, totalAmount, payTime);
    }

    @Override
    public CreateOrderAggregate queryOrder(String orderId) {
        return orderRepository.queryOrder(orderId);
    }

    @Override
    public void deliverGoods(String orderId) {
        orderRepository.deliverGoods(orderId);
    }

    @Override
    public List<String> queryReplenishmentOrder() {
        return orderRepository.queryReplenishmentOrder();
    }

    @Override
    public List<String> queryNoPayNotifyOrderList() {
        return orderRepository.queryNoPayNotifyOrderList();
    }

    @Override
    public String queryNoPayNotifyOrder() {
        return orderRepository.queryNoPayNotifyOrder();
    }

    @Override
    public List<String> queryTimeoutCloseOrderList() {
        return orderRepository.queryTimeoutCloseOrderList();
    }

    @Override
    public boolean changeOrderClose(String orderId) {
        return orderRepository.changeOrderClose(orderId);
    }

    @Override
    public List<ProductEntity> queryProductList() {
        return orderRepository.queryProductList();
    }
}
